
#region Imports

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Configuration.Provider;
using System.Text;
using System.Web.Configuration;

#endregion

namespace Justa.Data.Provider
{
    /// <summary>
    /// 
    /// </summary>
    /// 
    public class DataAccessProviderManager
    {
        /// <summary>
        /// 
        /// </summary>
        /// 
        private DataAccessProvider defaultProvider;

        /// <summary>
        /// 
        /// </summary>
        /// 
        private DataAccessProviderCollection providers;

        /// <summary>
        /// 
        /// </summary>
        /// 
        static DataAccessProviderManager()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        private DataAccessProviderManager()
        {
            Initialize();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        private void Initialize()
        {
            DataAccessProviderSection section =
                ConfigurationManager.GetSection(DataAccessProviderSection.ConfigurationSection) as DataAccessProviderSection;

            if (section == null)
            {
                throw new ProviderException("Please define a default provider configuration.");
            }

            providers = new DataAccessProviderCollection();
            ProvidersHelper.InstantiateProviders(section.DataAccessProviders, providers, typeof(DataAccessProvider));
            providers.SetReadOnly();

            defaultProvider = providers[section.DefaultDataAccessProvider];
            if (defaultProvider == null)
            {
                throw new ProviderException("Please define a default data access provider.");
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public static DataAccessProviderManager Instance
        {
            get
            {
                return DataAccessProviderManagerSingleton.soleInstance;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        internal class DataAccessProviderManagerSingleton
        {
            /// <summary>
            /// 
            /// </summary>
            /// 
            static DataAccessProviderManagerSingleton()
            {
            }

            static internal readonly DataAccessProviderManager soleInstance = new DataAccessProviderManager();
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public DataAccessProvider DefaultProvider
        {
            get
            {
                return defaultProvider;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        public DataAccessProviderCollection Providers
        {
            get
            {
                return providers;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="name"></param>
        /// 
        /// <returns></returns>
        /// 
        public DataAccessProvider GetProvider(string name)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentException("Specified provider name is null.");
            }
            
            return Providers[name];
        }
    }
}
